#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BigInt.h"

BigInt BigInt_Create()
{
	BigInt BigInt;
	
	BigInt.IsNegative=false;
	BigInt.Length=1;
	BigInt.Size=10;
	BigInt.Digits=malloc(sizeof(BigInt_Digit)*BigInt.Size);
	BigInt.Digits[0]=0;
	
	return BigInt;
}

void BigInt_Destroy(BigInt BigInt)
{
	free(BigInt.Digits);
}

void BigInt_SetFromInt(BigInt *BigInt, int Value)
{
	if (Value<0)
	{
		BigInt->IsNegative=true;
		Value=0-Value;
	}
	else
		BigInt->IsNegative=false;
	
	if (Value==0)
	{
		BigInt->Length=1;
		BigInt_Resize(BigInt);
		BigInt->Digits[0]=0;
		return;
	}
	
	BigInt->Length=0;
	BigInt_Digit Digit;
	while(Value>0)
	{
		Digit=Value%10;
		++BigInt->Length;
		BigInt_Resize(BigInt);
		BigInt->Digits[BigInt->Length-1]=Digit;
		
		Value/=10;
	}
}

/*
	FIXME:
		Check for null pointers from malloc and realloc
*/
void BigInt_SetFromLong(BigInt *BigInt, long Value)
{
	if (Value<0)
	{
		BigInt->IsNegative=true;
		Value=0-Value;
	}
	else
		BigInt->IsNegative=false;
	
	if (Value==0)
	{
		BigInt->Length=1;
		BigInt_Resize(BigInt);
		BigInt->Digits[0]=0;
		return;
	}
	
	BigInt->Length=0;
	BigInt_Digit Digit;
	while(Value>0)
	{
		Digit=Value%10;
		++BigInt->Length;
		BigInt_Resize(BigInt);
		BigInt->Digits[BigInt->Length-1]=Digit;
		
		Value/=10;
	}
}

void BigInt_Add(BigInt *Result, BigInt Number0, BigInt Number1)
{
	if (Number0.IsNegative==false && Number1.IsNegative==true)
	{
		Number1.IsNegative=false;
		BigInt_Sub(Result, Number0, Number1);
		Number1.IsNegative=true;
		return;
	}
	if (Number0.IsNegative==true && Number1.IsNegative==false)
	{
		Number0.IsNegative=false;
		BigInt_Sub(Result, Number1, Number0);
		Number0.IsNegative=true;
		return;
	}
	if (Number0.IsNegative==true && Number1.IsNegative==true)
	{
		Number0.IsNegative=false;
		Number1.IsNegative=false;
		BigInt_Sub(Result, Number0, Number1);
		Number0.IsNegative=true;
		Number1.IsNegative=true;
		BigInt_Negate(Result);
		return;
	}
	
	Result->Length=0;
	Result->IsNegative=false;
	
	Result->Size=Number0.Length+Number1.Length;
	Result->Digits=realloc(Result->Digits, sizeof(BigInt_Digit)*Result->Size);	
	
	int Carry=0, Position=0, Sum;
	while(Carry || Position<Number0.Length || Position<Number1.Length)
	{
		Sum=Carry;
		if (Position<Number0.Length)
			Sum+=Number0.Digits[Position];
		if (Position<Number1.Length)
			Sum+=Number1.Digits[Position];
		
		if (Sum>9)
		{
			Sum-=10;
			Carry=1;
		}
		else
			Carry=0;
		
		++Result->Length;
		BigInt_Resize(Result);
		Result->Digits[Position]=Sum;
		
		++Position;
	}
	
	BigInt_Clean(Result);
}

void BigInt_Sub(BigInt *Result, BigInt Number0, BigInt Number1)
{
	if (Number0.IsNegative==true && Number1.IsNegative==false)
	{
		Number0.IsNegative=false;
		BigInt_Sub(Result, Number0, Number1);
		Number0.IsNegative=true;
		BigInt_Negate(Result);
		return;
	}
	if (Number0.IsNegative==false && Number1.IsNegative==true)
	{
		Number1.IsNegative=false;
		BigInt_Add(Result, Number0, Number1);
		Number1.IsNegative=true;
		return;
	}
	if (Number0.IsNegative==true && Number1.IsNegative==true)
	{
		Number0.IsNegative=false;
		Number1.IsNegative=false;
		BigInt_Sub(Result, Number1, Number0);
		Number0.IsNegative=true;
		Number1.IsNegative=true;
		return;
	}
	if (BigInt_IsGreaterThan(Number1, Number0))
	{
		BigInt_Sub(Result, Number1, Number0);
		Result->IsNegative=true;
		return;
	}
	
	BigInt BackupNumber=BigInt_Create();
	BigInt_SetFromBigInt(&BackupNumber, Number0);
	Result->IsNegative=false;
	
	//Number0>=Number1>=0
	int Position=0, Digit, TempPosition;
	while(Position<BackupNumber.Length)
	{
		if (Position<Number1.Length)
		{
			if (BackupNumber.Digits[Position]<Number1.Digits[Position])
			{
				TempPosition=Position+1;
				while(BackupNumber.Digits[TempPosition]==0)
				{
					BackupNumber.Digits[TempPosition]=9;
					++TempPosition;
				}
				--BackupNumber.Digits[TempPosition];
				BackupNumber.Digits[Position]+=10;
			}
			Digit=BackupNumber.Digits[Position]-Number1.Digits[Position];		
		}
		else
			Digit=BackupNumber.Digits[Position];

		Result->Length=Position+1;
		BigInt_Resize(Result);
		Result->Digits[Position]=Digit;
		
		++Position;
	}
	
	BigInt_Destroy(BackupNumber);
	BigInt_Clean(Result);
	
	return;
}

int BigInt_GetDecimalLength(BigInt Number)
{
	return Number.Length+Number.IsNegative;
}

void BigInt_GetAsString(BigInt Number, char *String)
{
	int Position;
	if (Number.IsNegative)
		String[0]='-';
	for(Position=0;Position<Number.Length;++Position)
		String[Number.Length-Position-1+Number.IsNegative]=Number.Digits[Position]+48;
	String[Number.Length+Number.IsNegative]=0;
	
	return;
}

void BigInt_Negate(BigInt *Number)
{
	Number->IsNegative*=-1;
}

int BigInt_IsEqualTo(BigInt Number0, BigInt Number1)
{
	return !BigInt_IsNotEqualTo(Number0, Number1);
}

int BigInt_IsNotEqualTo(BigInt Number0, BigInt Number1)
{
	if (Number0.Length!=Number1.Length)
		return 1;
		
	if (Number0.IsNegative!=Number1.IsNegative)
		return 1;
		
	int Position;
	for(Position=0;Position<Number0.Length;++Position)
	{
		if (Number0.Digits[Position]!=Number1.Digits[Position])
			return 1;
	}
	
	return 0;
}

int BigInt_IsLessThanOrEqualTo(BigInt Number0, BigInt Number1)
{
	return !BigInt_IsGreaterThan(Number0, Number1);
}

int BigInt_IsGreaterThanOrEqualTo(BigInt Number0, BigInt Number1)
{
	return !BigInt_IsLessThan(Number0, Number1);
}

int BigInt_IsLessThan(BigInt Number0, BigInt Number1)
{
	if (Number0.IsNegative==true && Number1.IsNegative==false)
		return 1;
		
	if (Number0.IsNegative==false && Number1.IsNegative==true)
		return 0;
	
	if (Number0.IsNegative==false && Number1.IsNegative==false)
	{
		if (Number0.Length<Number1.Length)
			return 1;
			
		if (Number0.Length>Number1.Length)
			return 0;
			
		int Position;
		for(Position=Number0.Length-1;Position>=0;--Position)
		{
			if (Number0.Digits[Position]<Number1.Digits[Position])
				return 1;
				
			if (Position==0 || Number0.Digits[Position]>Number1.Digits[Position])
				return 0;
		}
	}
	
	if (Number0.IsNegative==true && Number1.IsNegative==true)
	{
		Number0.IsNegative=false;
		Number1.IsNegative=false;
		int Return=BigInt_IsGreaterThan(Number0, Number1);
		Number0.IsNegative=true;
		Number1.IsNegative=true;
		return Return;
	}
	
	return 0;
}

int BigInt_IsGreaterThan(BigInt Number0, BigInt Number1)
{
	if (Number0.IsNegative==true && Number1.IsNegative==false)
		return 0;
		
	if (Number0.IsNegative==false && Number1.IsNegative==true)
		return 1;
	
	if (Number0.IsNegative==false && Number1.IsNegative==false)
	{
		return !BigInt_IsEqualTo(Number0, Number1) && !BigInt_IsLessThan(Number0, Number1);
	}
	
	if (Number0.IsNegative==true && Number1.IsNegative==true)
	{
		Number0.IsNegative=false;
		Number1.IsNegative=false;
		int Return=BigInt_IsLessThan(Number0, Number1);
		Number0.IsNegative=true;
		Number1.IsNegative=true;
		return Return;
	}
	
	return 0;
}

void BigInt_SetFromBigInt(BigInt *Output, BigInt Value)
{
	Output->Length=Value.Length;
	BigInt_Resize(Output);
	Output->IsNegative=Value.IsNegative;
	memcpy(Output->Digits, Value.Digits, sizeof(BigInt_Digit)*Output->Length);
}

void BigInt_Mul(BigInt *Result, BigInt Number0, BigInt Number1)
{
	if (Number0.IsNegative==true && Number1.IsNegative==false)
	{
		BigInt_Negate(&Number0);
		BigInt_Mul(Result, Number0, Number1);
		BigInt_Negate(Result);
		BigInt_Negate(&Number0);
		return;
	}
	if (Number0.IsNegative==false && Number1.IsNegative==true)
	{
		BigInt_Negate(&Number1);
		BigInt_Mul(Result, Number0, Number1);
		BigInt_Negate(Result);
		BigInt_Negate(&Number1);
		return;
	}
	if (Number0.IsNegative==true && Number1.IsNegative==true)
	{
		BigInt_Negate(&Number0);
		BigInt_Negate(&Number1);
		BigInt_Mul(Result, Number0, Number1);
		BigInt_Negate(&Number0);
		BigInt_Negate(&Number1);
		return;
	}
	if (BigInt_IsGreaterThan(Number1, Number0))
	{
		BigInt_Mul(Result, Number1, Number0);
		return;
	}
	
	if (Number0.Length<4 || Number1.Length<4)
		BigInt_SlowMul(Result, Number0, Number1);
	else
		BigInt_FastMul(Result, Number0, Number1);
	return;
}

void BigInt_FastMul(BigInt *Result, BigInt Number0, BigInt Number1)
{
	if (Number0.IsNegative==true && Number1.IsNegative==false)
	{
		BigInt_Negate(&Number0);
		BigInt_FastMul(Result, Number0, Number1);
		BigInt_Negate(Result);
		BigInt_Negate(&Number0);
		return;
	}
	if (Number0.IsNegative==false && Number1.IsNegative==true)
	{
		BigInt_Negate(&Number1);
		BigInt_FastMul(Result, Number0, Number1);
		BigInt_Negate(Result);
		BigInt_Negate(&Number1);
		return;
	}
	if (Number0.IsNegative==true && Number1.IsNegative==true)
	{
		BigInt_Negate(&Number0);
		BigInt_Negate(&Number1);
		BigInt_FastMul(Result, Number0, Number1);
		BigInt_Negate(&Number0);
		BigInt_Negate(&Number1);
		return;
	}
	if (BigInt_IsGreaterThan(Number1, Number0))
	{
		BigInt_FastMul(Result, Number1, Number0);
		return;
	}
	
	/*
	X=X1*10^M+X0
	Y=Y1*10^M+X1
	
	Z2=X1*Y1
	Z0=X0*Y0
	Z1=(X1+X0)*(Y1+Y0)-Z2-Z0
	P0=Z0
	P1=Z1*10^M
	P2=Z2*10^(2*M)
	XY=P2+P1+P0
	*/
	
	/* Choose M */
	int M;
	if (Number0.Length<Number1.Length)
		M=Number0.Length/2;
	else
		M=Number1.Length/2;
	
	/* Create X0, X1, Y0 and Y1 */
	BigInt X0=BigInt_Create(),X1=BigInt_Create(),Y0=BigInt_Create(),Y1=BigInt_Create();
	
	X1.Length=Number0.Length-M;
	X1.Size=X1.Length;
	X0.Length=M;
	X0.Size=M;
	Y1.Length=Number1.Length-M;
	Y1.Size=Y1.Length;
	Y0.Length=M;
	Y0.Size=M;
	
	X0.Digits=realloc(X0.Digits, sizeof(BigInt_Digit)*X0.Length);
	X1.Digits=realloc(X1.Digits, sizeof(BigInt_Digit)*X1.Length);
	Y0.Digits=realloc(Y0.Digits, sizeof(BigInt_Digit)*Y0.Length);
	Y1.Digits=realloc(Y1.Digits, sizeof(BigInt_Digit)*Y1.Length);
	
	int Position;
	for(Position=0;Position<M;++Position)
	{
		X0.Digits[Position]=Number0.Digits[Position];
		Y0.Digits[Position]=Number1.Digits[Position];
	}
	for(Position=0;Position<X1.Length;++Position)
		X1.Digits[Position]=Number0.Digits[Position+M];
	for(Position=0;Position<Y1.Length;++Position)
		Y1.Digits[Position]=Number1.Digits[Position+M];
	
	/* Compute Z2 and Z0 */
	BigInt Z2=BigInt_Create();
	BigInt Z0=BigInt_Create();
	
	BigInt_Mul(&Z2, X1, Y1);
	BigInt_Mul(&Z0, X0, Y0);
	
	/* Compute Z1 */
	BigInt Z1=BigInt_Create();
	BigInt Temp0=BigInt_Create();
	BigInt Temp1=BigInt_Create();
	BigInt Temp2=BigInt_Create();
	
	BigInt_Add(&Temp0, X0, X1);
	BigInt_Add(&Temp1, Y0, Y1);
	BigInt_Mul(&Temp2, Temp0, Temp1);
	BigInt_Sub(&Temp1, Temp2, Z2);
	BigInt_Sub(&Z1, Temp1, Z0);
	
	/* Work out P0, P1 and P2 */
	BigInt P0=BigInt_Create();
	BigInt P1=BigInt_Create();
	BigInt P2=BigInt_Create();
	
	BigInt_SetFromBigInt(&P0, Z0);
	
	P1.Length=BigInt_GetDecimalLength(Z1)+M;
	P2.Length=BigInt_GetDecimalLength(Z2)+2*M;
	BigInt_Resize(&P1);
	BigInt_Resize(&P2);
	
	for(Position=0;Position<M;++Position)
		P1.Digits[Position]=0;
	for(Position=0;Position<2*M;++Position)
		P2.Digits[Position]=0;
	for(Position=M;Position<P1.Length;++Position)
		P1.Digits[Position]=Z1.Digits[Position-M];
	for(Position=2*M;Position<P2.Length;++Position)
		P2.Digits[Position]=Z2.Digits[Position-2*M];
	
	/* Finally compute XY */
	BigInt_Add(&Temp0, P0, P1);
	BigInt_Add(Result, Temp0, P2);	
	
	/* Clean up */
	BigInt_Destroy(X0);
	BigInt_Destroy(X1);
	BigInt_Destroy(Y0);
	BigInt_Destroy(Y1);
	BigInt_Destroy(Z0);
	BigInt_Destroy(Z1);
	BigInt_Destroy(Z2);
	BigInt_Destroy(Temp0);
	BigInt_Destroy(Temp1);
	BigInt_Destroy(Temp2);
	BigInt_Destroy(P0);
	BigInt_Destroy(P1);
	BigInt_Destroy(P2);
}

void BigInt_SlowMul(BigInt *Result, BigInt Number0, BigInt Number1)
{
	if (Number0.IsNegative==true && Number1.IsNegative==false)
	{
		BigInt_Negate(&Number0);
		BigInt_SlowMul(Result, Number0, Number1);
		BigInt_Negate(Result);
		BigInt_Negate(&Number0);
		return;
	}
	if (Number0.IsNegative==false && Number1.IsNegative==true)
	{
		BigInt_Negate(&Number1);
		BigInt_SlowMul(Result, Number0, Number1);
		BigInt_Negate(Result);
		BigInt_Negate(&Number1);
		return;
	}
	if (Number0.IsNegative==true && Number1.IsNegative==true)
	{
		BigInt_Negate(&Number0);
		BigInt_Negate(&Number1);
		BigInt_SlowMul(Result, Number0, Number1);
		BigInt_Negate(&Number0);
		BigInt_Negate(&Number1);
		return;
	}
	if (BigInt_IsGreaterThan(Number1, Number0))
	{
		BigInt_SlowMul(Result, Number1, Number0);
		return;
	}
	
	BigInt ResultTemp=BigInt_Create();
	BigInt Number1Backup=BigInt_Create();
	BigInt_SetFromBigInt(&Number1Backup, Number1);
	
	BigInt_SetFromBigInt(Result, Number0);
	
	BigInt One=BigInt_Create();
	BigInt_SetFromInt(&One, 1);
	
	while(BigInt_IsGreaterThan(Number1Backup, One))
	{
		BigInt_SetFromBigInt(&ResultTemp, *Result);
		BigInt_Add(Result, ResultTemp, Number0);
		BigInt_Dec(&Number1Backup);
	}
	
	BigInt_Destroy(Number1Backup);
	BigInt_Destroy(ResultTemp);
	BigInt_Destroy(One);
	
	BigInt_Clean(Result);
}

void BigInt_Inc(BigInt *Number)
{
	BigInt One=BigInt_Create();
	BigInt_SetFromInt(&One, 1);
	
	BigInt NumberBackup=BigInt_Create();
	BigInt_SetFromBigInt(&NumberBackup, *Number);
	
	BigInt_Add(Number, NumberBackup, One);
	
	BigInt_Destroy(One);
	BigInt_Destroy(NumberBackup);
	
	BigInt_Clean(Number);
}

void BigInt_Dec(BigInt *Number)
{
	BigInt One=BigInt_Create();
	BigInt_SetFromInt(&One, 1);
	
	BigInt NumberBackup=BigInt_Create();
	BigInt_SetFromBigInt(&NumberBackup, *Number);
	
	BigInt_Sub(Number, NumberBackup, One);
	
	BigInt_Destroy(One);
	BigInt_Destroy(NumberBackup);
	
	BigInt_Clean(Number);
}

void BigInt_Clean(BigInt *Number)
{
	while(Number->Length>1 && Number->Digits[Number->Length-1]==0)
		--Number->Length;
}

void BigInt_Div(BigInt *Result, BigInt Number0, BigInt Number1)
{	
	BigInt Number0A=BigInt_Create();
	BigInt Number0B=BigInt_Create();
	
	BigInt_SetFromBigInt(&Number0A, Number0);
	
	BigInt_SetFromInt(Result, 0);

	while(BigInt_IsGreaterThanOrEqualTo(Number0A, Number1))
	{
		BigInt_SetFromBigInt(&Number0B, Number0A);
		BigInt_Sub(&Number0A, Number0B, Number1);
		
		BigInt_Inc(Result);
	}
	
	BigInt_Destroy(Number0A);
	BigInt_Destroy(Number0B);
	
	BigInt_Clean(Result);
}

void BigInt_Mod(BigInt *Result, BigInt Number0, BigInt Number1)
{	
	BigInt ResultTemp=BigInt_Create();
	BigInt_SetFromBigInt(Result, Number0);

	while(BigInt_IsGreaterThanOrEqualTo(*Result, Number1))
	{
		BigInt_SetFromBigInt(&ResultTemp, *Result);
		BigInt_Sub(Result, ResultTemp, Number1);
	}
	
	BigInt_Destroy(ResultTemp);
	
	BigInt_Clean(Result);
}

void BigInt_Factorial(BigInt *Result, BigInt Number)
{
	BigInt_SetFromInt(Result, 1);
	
	BigInt TempNumber=BigInt_Create();
	BigInt_SetFromBigInt(&TempNumber, Number);
	
	BigInt TempResult=BigInt_Create();
	
	BigInt One=BigInt_Create();
	BigInt_SetFromInt(&One, 1);
	
	while(BigInt_IsGreaterThan(TempNumber, One))
	{
		BigInt_SetFromBigInt(&TempResult, *Result);
		BigInt_Mul(Result, TempResult, TempNumber);
		
		BigInt_Dec(&TempNumber);
	}
	
	BigInt_Destroy(TempNumber);
	BigInt_Destroy(TempResult);
	BigInt_Destroy(One);
	
	BigInt_Clean(Result);
}

void BigInt_Debug(BigInt BigInt)
{
	printf("BigInt:\n");
	printf("	Size: %i\n Length: %i\n IsNegative: %i\n", BigInt.Size, BigInt.Length, BigInt.IsNegative);
	
	printf("	Digits (in reverse): ");
	int Position;
	for(Position=0;Position<BigInt.Length;++Position)
	{
		printf("%i ", BigInt.Digits[Position]);
	}
	printf("\n");
}

void BigInt_Sqrt(BigInt *Result, BigInt Number)
{
	BigInt Temp=BigInt_Create();
	BigInt Last=BigInt_Create();
	BigInt Two=BigInt_Create();
	
	BigInt_SetFromInt(&Two, 2);
	BigInt_SetFromInt(&Last, 0);
	BigInt_SetFromInt(Result, 10);
	
	while(BigInt_IsNotEqualTo(Last, *Result))
	{
		BigInt_SetFromBigInt(&Last, *Result);
		BigInt_Div(&Temp, Number, *Result);
		BigInt_Add(&Temp, Temp, *Result);
		BigInt_Div(Result, Temp, Two);
	}
	
	BigInt_Destroy(Temp);
	BigInt_Destroy(Last);
	BigInt_Destroy(Two);
}

void BigInt_Pow(BigInt *Result, BigInt Base, BigInt Exponent)
{
	BigInt Zero=BigInt_Create();
	BigInt One=BigInt_Create();
	BigInt Two=BigInt_Create();
	BigInt Temp0=BigInt_Create();
	BigInt Temp1=BigInt_Create();
	
	BigInt_SetFromInt(&Zero, 0);
	BigInt_SetFromInt(&One, 1);
	BigInt_SetFromInt(&Two, 2);
	
	if (BigInt_IsEqualTo(Exponent, Zero))
	{
		BigInt_SetFromInt(Result, 1);
	}
	else if (BigInt_IsLessThan(Exponent, Zero))
	{
		BigInt_SetFromInt(Result, 1);
	}
	else if (BigInt_IsEqualTo(Exponent, One))
	{
		BigInt_SetFromBigInt(Result, Base);
	}
	else
	{
		BigInt_Mod(&Temp0, Exponent, Two);
		if (BigInt_IsEqualTo(Temp0, One))
		{
			BigInt_Div(&Temp0, Exponent, Two);
			BigInt_Pow(&Temp1, Base, Temp0);
			BigInt_Mul(&Temp0, Temp1, Temp1);
			BigInt_Mul(Result, Base, Temp0);
		}
		else
		{
			BigInt_Div(&Temp0, Exponent, Two);
			BigInt_Pow(&Temp1, Base, Temp0);
			BigInt_Mul(Result, Temp1, Temp1);
		}
	}
	
	BigInt_Destroy(Zero);
	BigInt_Destroy(One);
	BigInt_Destroy(Two);
	BigInt_Destroy(Temp0);
	BigInt_Destroy(Temp1);
	
	return;
}

void BigInt_Resize(BigInt *BigInt)
{
	if (BigInt->Length>BigInt->Size)
	{
		BigInt->Size=BigInt->Length;
		BigInt->Digits=realloc(BigInt->Digits, BigInt->Size*sizeof(BigInt_Digit));
	}
}

void BigInt_Abs(BigInt *BigInt)
{
	BigInt->IsNegative=false;
}

void BigInt_GCD(BigInt *Result, BigInt Number0, BigInt Number1)
{
	BigInt Temp0=BigInt_Create();
	BigInt Number1B=BigInt_Create();
	BigInt Zero=BigInt_Create();
	
	BigInt_SetFromBigInt(Result, Number0);
	BigInt_SetFromBigInt(&Number1B, Number1);
	BigInt_SetFromInt(&Zero, 0);
	
	while(BigInt_IsNotEqualTo(Number1B, Zero))
	{
		BigInt_SetFromBigInt(&Temp0, Number1B);
		BigInt_Mod(&Number1B, *Result, Temp0);
		BigInt_SetFromBigInt(Result, Temp0);
	}
	
	BigInt_Destroy(Temp0);
	BigInt_Destroy(Zero);
	BigInt_Destroy(Number1B);
}

void BigInt_LCM(BigInt *Result, BigInt Number0, BigInt Number1)
{
	BigInt Temp0=BigInt_Create();
	BigInt Temp1=BigInt_Create();
	
	BigInt_GCD(&Temp0, Number0, Number1);
	BigInt_Mul(&Temp1, Number0, Number1);
	Temp1.IsNegative=false;
	
	BigInt_Div(Result, Temp1, Temp0);
	
	BigInt_Destroy(Temp0);
	BigInt_Destroy(Temp1);
}

void BigInt_SetFromString(BigInt *BigInt, char *Value)
{
	int StringIndex=0, NumberIndex;
	
	BigInt->IsNegative=false;
	BigInt->Length=0;
	BigInt->Size=strlen(Value);
	BigInt->Digits=realloc(BigInt->Digits, sizeof(BigInt_Digit)*BigInt->Size);
	
	if (Value[0]=='-')
	{
		BigInt->IsNegative=true;
		StringIndex=1;
	}
	else if (Value[0]=='+')
		StringIndex=1;
		
	NumberIndex=strlen(Value)-StringIndex-1;
	while(Value[StringIndex]!=0)
	{
		BigInt->Digits[NumberIndex]=Value[StringIndex];
		++BigInt->Length;
		++StringIndex;
		--NumberIndex;
	}
}